﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace TransportLayer.NodeLibrary
{
    public class Node : Cleaner
    {
        private int id;
        public int Id { get { return id; } }

        private string name;
        public string Name { get { return name; } set { name = value; } }

        private NodeSNP snp;
        public NodeSNP Snp { get { return snp; } }

        private Log log;
        public Log Log { get { return log; } }

        private PortIn[] inportsgroup; //porty wejsciowe wezla
        public PortIn[] PortsIn { get { return inportsgroup; } }

        private PortOut[] outportsgroup; //porty wyjsciowe wezla
        public PortOut[] PortsOut { get { return outportsgroup; } }

        private SFMLRM sfm; //= new Matrix();  //Matrix wezla czyli tablica routingu
        public SFMLRM Sfm { get { return sfm; } }

        public int PositionX;
        public int PositionY;

        public float Delay { get; private set; }
        public bool Accessible { get; private set; }
        public string Type { get; private set; }


        public Node(TransportLayer.Node node, int managerPort)
        {

            PositionX = node.PositionX;
            PositionY = node.PositionY;

            this.id = node.Id;
            this.name = (string)node.Name.Clone();

            inportsgroup = new PortIn[node.PortsIn.Count];
            outportsgroup = new PortOut[node.PortsOut.Count];
            sfm = new SFMLRM(this);

            foreach (TransportLayer.PortIn portIn in node.PortsIn)
            {
                PortIn port = new PortIn(portIn.Id);
                port.SetReceiver(this.sfm);
                inportsgroup[portIn.Id] = port;
            }

            foreach (TransportLayer.PortOut portOut in node.PortsOut)
            {
                outportsgroup[portOut.Id] = new PortOut(portOut.Id);
            }

            this.Delay = node.Delay;
            this.Type = node.Type;
            this.Accessible = node.Accessible;
            this.log = new Log("Log urzadzenia " + name);
            this.snp = new NodeSNP(this, managerPort);

        }



        public void Clean()
        {
            foreach (Cleaner p in PortsIn)
            {
                p.Clean();
            }
            foreach (Cleaner p in PortsOut)
            {
                p.Clean();
            }

            snp.Clean();
        }
        //metods that give list 
        public string DownPortIn()
        { 
            string back= "";
            foreach (PortIn p in PortsIn)
            {
                if (p.Connected == false)
                    back += p.PortID + "#";
            }
            return back;
        }

        public string UpPortIn()
        {
            string back = "";
            foreach (PortIn p in PortsIn)
            {
                if (p.Connected == true)
                    back += p.PortID + "#";
            }
            return back;
        }

        public string DownPortOut()
        {
            string back = "";
            foreach (PortOut p in PortsOut)
            {
                if(p.Connected == false)
                back +=  p.PortID+"#";
            }
            return back;
        }

        public string UpPortOut()
        {
            string back = "";
            foreach (PortOut p in PortsOut)
            {
                if (p.Connected == true)
                    back += p.PortID + "#";
            }
            return back;
        }
 
        public List<string> AvailablePortsIn 
        {
            get
            {
                List<string> port = new List<string>();
                foreach(PortIn p in PortsIn)
                {
                    if (p.Connected)
                        port.Add(String.Format("[{0}]->UP", p.PortID));
                    else
                        port.Add(String.Format("[{0}]->DOWN", p.PortID));
                           
                }
                return port;
            }
        }

        public List<string> AvailablePortsOut
        {
            get
            {
                List<string> port = new List<string>();
                foreach (PortOut p in PortsOut)
                {
                    if (p.Connected)
                        port.Add(String.Format("[{0}]->UP", p.PortID));
                    else
                        port.Add(String.Format("[{0}]->DOWN", p.PortID));

                }
                return port;
            }
        }

       
    }
}
